package web.filter;

import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;
import web.entity.Security_UserDetail;
import web.utils.JwtUtil;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Objects;


@Component
public class Security_TokenFilter extends OncePerRequestFilter {

    @Autowired
    RedisTemplate redisTemplate;


    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
       /*从请求头中获取token*/
        String mydx_token = request.getHeader("mydx_token");
        if (!StringUtils.hasText(mydx_token)) {
            //todo 为什么不直接return?
            filterChain.doFilter(request, response);
            return;
            /*doFilter 没有token，就不进行token解析，就不会有信息存入SecurityContextHolder，后面的过滤器是
             * 能够检测到没有登录的
             * */
            /*return 因为过滤器是是有来有回的。doFilter过后，始终会返回过来往下执行，如果没有return，
            后续依然会往下执行
             * */
        }
        //解析token获取id
        String userid = "";
        try {
            Claims claims = JwtUtil.parseJWT(mydx_token);
            userid = claims.getSubject();
        } catch (Exception e) {
//            e.printStackTrace();
            filterChain.doFilter(request, response);
            return;
//            throw new RuntimeException("非法token!");
        }
        //从reids中通过id获取用户信息
        String redisKey = userid;
        ValueOperations valueOperations = redisTemplate.opsForValue();
        Security_UserDetail userDetail = (Security_UserDetail) valueOperations.get(redisKey);

        if (Objects.isNull(userDetail)) {
            return;
            //            throw new RuntimeException("非法token!");
        }
        //todo 没有权限信息
        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken =
                new UsernamePasswordAuthenticationToken(userDetail, null, userDetail.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
        filterChain.doFilter(request, response);
    }
}
